const router = require('koa-router')();
const cc = require('../conCtl');
const js = require('../jsCtl');
const db = require('../dbCtl');
const pc = require('../projectCtl');
const schedule = require('node-schedule');



const storeDialSchedule = {
  item: {}
};

const loopInterval = 30000;//抽奖间隔时间
/**
 * 系统启动，初始化正在抽奖的九宫格活动，以及待抽奖的用户
 */
const initDialOnce = (gameInfo) => {
  return new Promise(async r => {
    const game = { info: gameInfo };
    //初始化当前活动奖品队列
    game.prizes = await db.model('t_gameDial_prize a').join('t_goods b on a.goods_id=b.id').where('a.game_id=?', game.info.id).field('a.*,b.details,b.name,b.market_price').orderBy('a.prize_level').select();
    //初始化当前活动用户队列
    game.users = await db.model('t_gameDial_queue a').field('1 as type,a.*,b.*').join('t_users b on a.openid=b.openid').where('a.game_id=?&&a.state=1', game.info.id).select();
    pc.storeDial.gameList[game.info.id] = game;

    let level = 0;
    for (let i = 0; i < game.prizes.length; i++) {
      const element = game.prizes[i];
      if (level == element.prize_level) {
        continue;
      } else {
        element.state = 1;
        await db.model('t_gameDial_prize').where('prize_id=?', element.prize_id).update({ state: 1 });
        level = element.prize_level;
      }
    }
    //清除现有定时器
    if (storeDialSchedule.item[game.info.id]) {
      clearInterval(storeDialSchedule.item[game.info.id]);
    }
    let time = Date.parse(new Date()) / 1000;//获取当前时间戳
    if (game.info.dt1 <= time) {
      console.log('九宫格抽奖开始时间:', new Date());
      //开启定时抽奖器循环
      setTimeout(() => {
        loopDial(game);
      }, loopInterval);
    } else {
      //获取活动开奖的时间
      var date = new Date(game.info.dt1 * 1000);
      //创建定时器
      storeDialSchedule.item[game.info.id] = schedule.scheduleJob(date, () => {
        console.log('九宫格抽奖开始时间:', date);
        //开启定时抽奖器循环
        setTimeout(() => {
          loopDial(game);
        }, loopInterval);
      });
    }
    r();
  })
}
(async () => {
  await pc.initSettings();//初始化环境变量
  //查询所有正在进行的活动
  let games = await db.model('t_gameDial').where('state=2').select();
  
  for (let i = 0; i < games.length; i++) {
    await initDialOnce(games[i]);
  }
})();

//循环抽奖方法
const loopDial = async (game) => {
  let time = Date.parse(new Date()) / 1000;//获取当前时间戳
  //判断当前活动是否截止并且活动中抽奖用户队列是否为空
  if (game.info.state == 4) {
    console.log('九宫格抽奖结束时间:', new Date());
    pc.storeDial.gameList[game.info.id].users = [];//删除正在队列中的九宫格抽奖队列
    delete pc.storeDial.gameList[game.info.id];//删除正在队列中的九宫格抽奖活动
    return;
  }
  if (game.info.dt2 < time && game.users.length == 0 && game.info.state == 2) {
    //如果截止修改活动状态已结束
    await db.model('t_gameDial').where('id=?', game.info.id).update({ state: 3 });
    console.log('九宫格抽奖结束时间:', new Date());
    delete pc.storeDial.gameList[game.info.id];//删除正在队列中的九宫格抽奖活动
    return;
  }
  let robot_winner_list = "";
  let addRobot = () => {
    return new Promise(async r => {
      //随机获得一个机器人

      let robot = await pc.createRobot(robot_winner_list);
      if (robot) {
        //添加机器人进入缓存队列
        game.users.push(js.regroup(robot, ['nick', 'headurl'], { openid: robot.id, game_id: game.info.id, type: 2 }));
        robot_winner_list += robot.id + ",";
        robot_winner_list = robot_winner_list.substr(0, robot_winner_list.length - 1);
      }
      r();
    });
  };

  //1.根据队列用户数量判断是否插入机器人排队
  let min_number = pc.storeSettings.dial_condition_number;
  let max_number = pc.storeSettings.dial_condition_number_max;
  if (js.compareDate(game.info.dt2) || game.users.length > max_number) {
    //如果队列人数大于max,或者活动已结束,什么都不做
  } else if (game.info.dt2 >= time) {
    if (game.users.length < min_number) {//如果队列人数小于min
      let count = min_number - game.users.length;//增加差数(count)个机器人
      for (let i = 0; i < count; i++) {//循环差数(count)增加机器人
        await addRobot();
      }
    } else {//如果队列人数大于min并且小于max,增加0-3个机器人
      if (js.randomNum(1, 100) > 50) {
        await addRobot();
      } if (js.randomNum(1, 100) > 50) {
        await addRobot();
      } if (js.randomNum(1, 100) > 50) {
        await addRobot();
      }
    }
  }

  //2.抽奖
  //获取当前抽奖人
  game.curUser = game.users.shift();
  let cu = game.curUser;
  // let prize_last_level = -1;
  for (let index = game.prizes.length - 1; index >= 0; index--) {
    const prize = game.prizes[index];
    //判断当前奖品状态是否正在抽取
    if (prize.state != 1) {
      continue;
    }
    /** //判断当前奖品等级是否已经抽取
    if (prize_last_level >= prize.prize_level) {
      continue;
    }
    prize_last_level = prize.prize_level;**/
    // let random = 1;
    let random = js.randomNum(1, prize.base);
    if (prize.odd >= random) {//中奖
      if (cu.type == 2 && !prize.canRobot) {
        //机器人中奖，但不被允许
        game.curResult = {};
        continue;
      }
      await db.startTransaction(async (tran) => {
        if (cu.type == 1) {
          //插入中奖信息通知
          await tran.model('t_message').insert({ openid: cu.openid, type: 2, title: game.info.name, message: prize.name });
          //生成用户订单
          await tran.model('t_order').insert({ game_id: game.info.id, goods_id: prize.goods_id, openid: cu.openid, type: 3, state: 2 });
        }
        // 新增一条用户中奖纪录
        await tran.model('t_gameDial_winner').insert({ game_id: game.info.id, prize_id: prize.prize_id, openid: cu.openid, winnerType: cu.type });
        if (!game.winner) game.winner = [];
        game.winner.push({ openid: cu.openid, nick: cu.nick, headurl: cu.headurl, prize_id: prize.prize_level });//中奖信息存入缓存
        // 活动中奖奖品数量+1
        prize.outCount += 1;
        if (prize.amount <= prize.outCount) {//当前奖品已抽完
          //更新当前奖品state=0
          prize.state = 0;
          //删除game.prizes中当前奖品
          game.prizes.splice(index, 1);
          //查询当前奖品同级别的下一件奖品 newPrize,
          let newPrizeModel = await db.model('t_gameDial_prize').where('state=2&&game_id=?&&prize_level=?', game.info.id, prize.prize_level).orderBy('dt').select(1, 1);
          if (newPrizeModel.length) {
            //添加抽奖奖品，并修改数据库奖品状态
            newPrize = newPrizeModel[0];
            newPrize.state = 1;
            game.prizes.push(newPrize);
            await db.model('t_gameDial_prize').insertOrUpdate(js.regroup(newPrize,['prize_id','game_id','goods_id','prize_level','amount','outCount','base','odd','dt','state','canRobot']));
          }
        }
        //将修改同步到数据库
        await tran.model('t_gameDial_prize').insertOrUpdate(js.regroup(prize,['prize_id','game_id','goods_id','prize_level','amount','outCount','base','odd','dt','state','canRobot']));
        //获取活动开奖的时间
        var date = new Date(game.info.dt2);
        console.log('开奖完成当前时间:', date);
      });

      game.curResult = prize;
      cc.err(`${cu.nick}(${cu.type == 2 ? 'robot' : 'user'})  抽奖中：level:${prize.prize_level},goods:${prize.goods_id},odd:${prize.odd}/${prize.base},random:${random}`);
      break;
    } else { //不中奖
      game.curResult = {};
      cc.log(`${cu.nick}(${cu.type == 2 ? 'robot' : 'user'})  抽奖不中：level:${prize.prize_level},goods:${prize.goods_id},odd:${prize.odd}/${prize.base},random:${random}`);
    }
  }
  await db.model('t_gameDial_queue').where('id=?', cu.id).update({ state: 2 });

  //开启下一次抽奖
  setTimeout(() => {
    loopDial(game);
  }, loopInterval);
};



/**
@hostpath = http://127.0.0.1/service/gameDial
 */

/** 获取九宫格抽奖活动列表
###
    GET {{hostpath}}?page=1&size=30
### */
router.get('/', async c => {
  let
    page = c.query.page || 1,
    size = c.query.size || 30;

  let moment = require('moment');
  let data = await db.model('t_gameDial')
    .where('state>0')
    .orderBy('dt1')
    .select(page, size);
  for (let i = 0; i < data.length; i++) {
    data[i].dt1 = moment.unix(data[i].dt1).format('YYYY-MM-DD HH:mm:ss');
    data[i].dt2 = moment.unix(data[i].dt2).format('YYYY-MM-DD HH:mm:ss');

  }
  cc.send_list(c, data);
});

/** 创建活动/编辑活动
###
    POST {{hostpath}}
    Content-Type: application/json

    {
        "id" : "",
        "name":"九宫格抽奖123",
        "dt1":"2020-11-20 11:48:35",
        "dt2":"2020-11-20 12:00:39",
        "price":10,
        "img":"http://kexunyun.oss-cn-beijing.aliyuncs.com/20201118/512150000321401505221605672180423.jpg",
        "rules":"兑换规则如下;"
    }
### */
router.post('/', async c => {
  js.check_params(
    !c.request.body.name && '!名称' ||
    !c.request.body.dt1 && '!开始时间' ||
    !c.request.body.dt2 && '!截止时间' ||
    !c.request.body.price && '!奖票价格' ||
    !c.request.body.img && '!banner' ||
    !c.request.body.rules && '!兑换规则');

  let data = c.request.body;
  data.dt1 = js.parseUnitMS(data.dt1);
  data.dt2 = js.parseUnitMS(data.dt2);
  if (!c.request.body.id) {
    delete data.id;
  } else {
    let state = await db.model('t_gameDial').where('id=?', data.id).shift('', 'state');
    if (state == 2) js.throwObj('进行中的九宫格活动不允许修改');
  }

  let id = await db.model('t_gameDial')
    .insertOrUpdate(data);

  cc.send(c, { id });
});

/** 删除活动
###
    DELETE {{hostpath}}
    Content-Type: application/json

    {
        "id" : 1
    }
### */
router.del('/', async c => {
  js.check_params(!c.request.body.id && '!活动ID');

  let data = c.request.body;

  let state = await db.model('t_gameDial').where('id=?', data.id).shift('未找到指定对象', 'state');
  if (state == 2)
    js.throwObj('进行中的活动不可删除', js.rescode.fail);

  await db.model('t_gameDial').where('id=?', data.id).relyUpdate('删除失败', {
    state: 0
  });

  cc.send(c);
});

/** 上线
###
### */
router.post('/upline', async c => {
  js.check_params(!c.request.body.id && '!活动ID');

  await db.model('t_gameDial').where('id=?', c.request.body.id).relyUpdate('上线失败', { state: 2 });
  let gameInfo = await db.model('t_gameDial').where('state=2&&id=?', c.request.body.id).shift();
  await initDialOnce(gameInfo);
  cc.send(c);
});

/** 手动停止
###
### */
router.post('/stop', async c => {
  js.check_params(!c.request.body.id && '!活动ID');
  //修改九宫格活动状态
  await db.model('t_gameDial').where('id=?', c.request.body.id).relyUpdate('停止失败',{ state: 4 });
  //初始化缓存
  if (!js.isNullOrUndefined(pc.storeDial.gameList[c.request.body.id])); {
    pc.storeDial.gameList[c.request.body.id].info.state = 4;//修改正在队列中需要停止的九宫格活动状态
  }
  cc.send(c);
});


/***************************************************** 活动奖品 ************************************************************/



/** 获取活动奖品列表
###
    GET {{hostpath}}/prize?page=1&size=30&id=6
### */
router.get('/prize', async c => {
  js.check_params(!c.query.id && '!活动ID');

  let data = await db.model('t_gameDial_prize a').join('t_goods b on a.goods_id=b.id')
    .where('a.game_id=?', c.query.id)
    .orderBy('a.prize_level, a.dt')
    .select();
  cc.send_list(c, data);
});

/** 添加奖品
###
    POST {{hostpath}}/prize
    Content-Type: application/json

    {
        "game_id":"1",
        "goods_id":"14",
        "prize_level":"1",
        "amount":"5"
    }
### */
router.post('/prize', async c => {
  js.check_params(
    !c.request.body.game_id && '!活动ID' ||
    !c.request.body.goods_id && '!奖品ID' ||
    !c.request.body.prize_level && '!奖品等级' ||
    !js.isNumber(c.request.body.prize_level, 1, 7) && '!奖品等级');

  let data = c.request.body;
  delete data.id;

  await db.startTransaction(async (tran) => {
    await tran.model('t_goods').where('id=? && repertory_type=0', data.goods_id).update({ state: 2 });//只更新库存类型为0的商品（单件商品）
    await tran.model('t_gameDial_prize').insertOrUpdate(data);
  });

  cc.send(c);
});

/** 删除奖品
###
### */
router.del('/prize', async c => {
  js.check_params(
    !c.request.body.game_id && '!活动ID' ||
    !c.request.body.goods_id && '!奖品ID' ||
    !c.request.body.prize_level && '!奖品等级');

  let data = c.request.body;

  await db.startTransaction(async (tran) => {
    await tran.model('t_goods').where('id=? && repertory_type=0', data.goods_id).update({ state: 1 });//只更新库存类型为0的商品（单件商品），无限库存商品的state始终为1
    await tran.model('t_gameDial_prize').where('game_id=?&&goods_id=?&&prize_level=?', data.game_id, data.goods_id, data.prize_level).delete();
  });

  cc.send(c);
});

module.exports = router;